home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / labyte.zip / LABYTE.C < prev    next >
C/C++ Source or Header  |  1992-05-08  |  9KB  |  344 lines

  1.    /* ------------------------------------ */
  2.   /* --     Logical Answers Byte       -- */
  3.  /* --  Our Real Good Memory Manager  -- */
  4. /* ------------------------------------ */
  5.  
  6. #include <alloc.h>
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9.  
  10. #define LATRACE 1   /* Compile with LATRACE enabled               */
  11.                    /* To disable LATRACE, Comment this statement */
  12.  
  13. #include <LAByte.h>
  14.  
  15. void *MemAnchor = NULL;     /* First storage chain pointer */
  16. TRACETBL *TraceTbl = NULL;  /* Function trace table        */
  17.  
  18. char far *mem_getmain(char *Mod, int Line, char Funct, char Use, int Len)
  19. {
  20.  char far *Area, *Work;
  21.  unsigned long C, W;
  22.  MEMTBL *MemBlock, *MemWork;
  23.  
  24.     trace_entry('E', "Mem", __LINE__);  /* Trace Entry to Paragraph */
  25.  
  26.     C = farcoreleft();
  27.     W = Len + 9;
  28.     if (!(W < C))
  29.         return(NULL);
  30.     Area = farmalloc(W);
  31.     memset(Area, NULL, W);
  32.     memcpy(Area, "^MH^", MEMHDRLEN);
  33.     Work = Area + Len + MEMHDRLEN;
  34.     memcpy(Work, "^MT^", MEMHDRLEN);
  35.     Area = Area + MEMHDRLEN;
  36.     MemBlock = malloc(sizeof(MEMTBL));
  37.     MemBlock->MemOK = 0;
  38.     strcpy(MemBlock->MemMod, Mod);
  39.     MemBlock->MemLine = Line;
  40.     MemBlock->MemFun = Funct;
  41.     MemBlock->MemUse = Use;
  42.     MemBlock->MemLen = Len;
  43.     MemBlock->MemAddr = Area;
  44.     MemBlock->MemNext = MemAnchor;
  45.     MemBlock->MemPrev = NULL;
  46.     MemWork = MemAnchor;
  47.     MemWork->MemPrev = MemBlock;
  48.     MemAnchor = MemBlock;
  49.     return(Area);
  50. }
  51.  
  52. int mem_freemain(char *Mod, int Line, char far *Area)
  53. {
  54.  char far *Work;
  55.  MEMTBL *MemBlock, *MemWork;
  56.  
  57.     trace_entry('E', "Mem", __LINE__);  /* Trace Entry to Paragraph */
  58.  
  59.     MemBlock = MemAnchor;
  60.     if (MemBlock == NULL)
  61.     {
  62.         mem_cancel(Line, Mod, 1, MemBlock, Area);
  63.         return(-2);
  64.     }
  65.     for(;;)
  66.     {
  67.         if (MemBlock->MemAddr == Area)
  68.             break;
  69.         if (MemBlock->MemNext == NULL)
  70.         {
  71.             mem_cancel(Line, Mod, 2, MemBlock, Area);
  72.             return(-2);
  73.         }
  74.         MemBlock = MemBlock->MemNext;
  75.     }
  76.     MemWork = MemBlock->MemNext;
  77.     if (MemWork != NULL)
  78.     {
  79.         if (MemWork->MemPrev != MemBlock)
  80.         {
  81.             mem_cancel(Line, Mod, 3, MemWork, Area);
  82.             return(-2);
  83.         }
  84.     }
  85.     MemWork = MemBlock->MemPrev;
  86.     if (MemWork != NULL)
  87.     {
  88.         if (MemWork->MemNext != MemBlock)
  89.         {
  90.             mem_cancel(Line, Mod, 4, MemWork, Area);
  91.             return(-2);
  92.         }
  93.     }
  94.     Work = MemBlock->MemAddr;
  95.     Work = Work - MEMHDRLEN;
  96.     if (memcmp(Work, "^MH^", MEMHDRLEN) != 0)
  97.     {
  98.         mem_cancel(Line, Mod, 5, MemBlock, Area);
  99.         return(2);
  100.     }
  101.     Work = MemBlock->MemAddr;
  102.     Work = Work + MemBlock->MemLen;
  103.     if (memcmp(Work, "^MT^", MEMHDRLEN) != 0)
  104.     {
  105.         mem_cancel(Line, Mod, 6, MemBlock, Area);
  106.         return(-2);
  107.     }
  108.     MemWork = MemBlock->MemNext;
  109.     if (MemWork != NULL)
  110.         MemWork->MemPrev = MemBlock->MemPrev;
  111.     MemWork = MemBlock->MemPrev;
  112.     if (MemWork != NULL)
  113.         MemWork->MemNext = MemBlock->MemNext;
  114.     else
  115.         MemAnchor = MemBlock->MemNext;
  116.     Area = MemBlock->MemAddr;
  117.     Area = Area - MEMHDRLEN;
  118.     farfree(Area);
  119.     free(MemBlock);
  120.     return(0);
  121. }
  122.  
  123. int mem_cleanup(char *Mod, int Line, char Funct)
  124. {
  125.  char *Area;
  126.  int Ret;
  127.  MEMTBL *MemBlock, *MemWork, *Next, *Prev;
  128.  
  129.     trace_entry('E', "Mem", __LINE__);  /* Trace Entry to Paragraph */
  130.  
  131.     Ret = mem_scan();
  132.     if (Ret)
  133.     {
  134.         mem_cancel(Line, Mod, 10+Ret, MemBlock, NULL);
  135.         return(-2);
  136.     }
  137.  
  138.     MemBlock = MemAnchor;
  139.     for(;;)
  140.     {
  141.         Next = MemBlock->MemNext;
  142.         Prev = MemBlock->MemPrev;
  143.         if (MemBlock->MemFun == Funct)
  144.         {
  145.             if (Next != NULL)
  146.                 Next->MemPrev = Prev;
  147.             if (Prev != NULL)
  148.                 Prev->MemNext = Next;
  149.             else
  150.                 MemAnchor = Next;
  151.             Area = MemBlock->MemAddr;
  152.             Area = Area - MEMHDRLEN;
  153.             farfree(Area);
  154.             free(MemBlock);
  155.             MemBlock = Next;
  156.         }
  157.         if (Next == NULL)
  158.             break;
  159.         MemBlock = Next;
  160.     }
  161.     return(0);
  162. }
  163.  
  164. int mem_freeall(char *Mod, int Line)
  165. {
  166.  char far *Area;
  167.  int Ret;
  168.  MEMTBL *MemBlock, *MemWork;
  169.  
  170.     trace_entry('E', "Mem", __LINE__);  /* Trace Entry to Paragraph */
  171.  
  172.     Ret = mem_scan();
  173.     if (Ret)
  174.     {
  175.         mem_cancel(Line, Mod, 20+Ret, MemBlock, NULL);
  176.         return(-2);
  177.     }
  178.     MemBlock = MemAnchor;
  179.     for(;;)
  180.     {
  181.         Area = MemBlock->MemAddr;
  182.         Area = Area - MEMHDRLEN;
  183.         farfree(Area);
  184.         MemWork = MemBlock->MemNext;
  185.         free(MemBlock);
  186.         if (MemWork == NULL)
  187.             break;
  188.         MemBlock = MemWork;
  189.     }
  190.     MemAnchor = NULL;
  191.     return(0);
  192. }
  193.  
  194. int mem_scan()
  195. {
  196.  char far *Work;
  197.  MEMTBL *MemBlock, *MemWork;
  198.  
  199.     trace_entry('E', "Mem", __LINE__);  /* Trace Entry to Paragraph */
  200.  
  201.     MemBlock = MemAnchor;
  202.     for(;;)
  203.     {
  204.         if (MemBlock == NULL)
  205.             break;
  206.         MemWork = MemBlock->MemNext;
  207.         if (MemWork != NULL)
  208.         {
  209.             if (MemWork->MemPrev != MemBlock)
  210.             {
  211.                 return(1);
  212.             }
  213.         }
  214.         Work = MemBlock->MemAddr;
  215.         Work = Work - MEMHDRLEN;
  216.         if (memcmp(Work, "^MH^", MEMHDRLEN) != 0)
  217.         {
  218.             return(2);
  219.         }
  220.         Work = MemBlock->MemAddr;
  221.         Work = Work + MemBlock->MemLen;
  222.         if (memcmp(Work, "^MT^", MEMHDRLEN) != 0)
  223.         {
  224.             return(3);
  225.         }
  226.         MemBlock = MemBlock->MemNext;
  227.     }
  228.     return(0);
  229. }
  230.  
  231. void mem_cancel(int Line, char *Mod, int Code, void far *Memory, char far *Area)
  232. {
  233.  MEMTBL *MemBlock;
  234.  
  235.     MemBlock = Memory;
  236.     MemBlock->MemOK = Code;
  237.     puts("\n\n\n\n");
  238.     puts("            [  --  ERROR  --  ]\n\n");
  239.     puts("   A memory error has occurred as a result of a request");
  240.     printf("   from line %d of module %s.  The error code was %d",
  241.         Line, Mod, Code);
  242.     if (Area != NULL)
  243.         printf("        The pointer to the area is %p\n", Area);
  244.     puts("\n\n\n\n");
  245.     cancel_prog(4);
  246. }
  247.  
  248.  
  249.  
  250.   /* ------------------------- */
  251.  /*       LATrace Logic       */
  252. /* ------------------------- */
  253.  
  254. void trace_entry(char Type, char *Mod, int Line)
  255. {
  256.  int I;
  257.  
  258. #ifdef LATRACE
  259.     if (TraceTbl == NULL)
  260.     {
  261.         TraceTbl = malloc((TRACEELEMS * sizeof(TraceTbl->TraceElem[0])) + 8);
  262.         TraceTbl->Wrap = 'N';
  263.         TraceTbl->TracePtr = 0;
  264.     }
  265.     I = TraceTbl->TracePtr;
  266.     TraceTbl->TraceElem[I].Type = Type;
  267.     strcpy(TraceTbl->TraceElem[I].Mod, Mod);
  268.     TraceTbl->TraceElem[I].Line = Line;
  269.     ++TraceTbl->TracePtr;
  270.     if (TraceTbl->TracePtr > 99)
  271.     {
  272.         TraceTbl->Wrap = 'Y';
  273.         TraceTbl->TracePtr = 0;
  274.     }
  275. #endif
  276.     return;
  277. }
  278.  
  279.  
  280.  /* Dump the trace and memory information to a file names "LATrace.Lac" */
  281. /*  and end the program with the specified exit code.                 */
  282.  
  283. void cancel_prog(int ExitCode)
  284. {
  285.  int Start, Curr;
  286.  FILE *TraceFile;
  287.  MEMTBL *MemBlock, *MemWork;
  288.  
  289.     TraceFile = fopen("LATrace.Lac", "w");
  290.     if (TraceFile == NULL)
  291.         exit(ExitCode);
  292.  
  293. #ifdef LATRACE
  294.     fputs("----- Trace Table -----\n", TraceFile);
  295.     if (TraceTbl->Wrap == 'N')
  296.         Start = 0;
  297.     else
  298.         Start = TraceTbl->TracePtr;
  299.     Curr = Start;
  300.     for(;;)
  301.     {
  302.         fprintf(TraceFile, "T---%c---%s---%d\n",
  303.             TraceTbl->TraceElem[Curr].Type,
  304.             TraceTbl->TraceElem[Curr].Mod,
  305.             TraceTbl->TraceElem[Curr].Line);
  306.         ++Curr;
  307.         if (Curr == TraceTbl->TracePtr)
  308.             break;
  309.         if (Curr > 99)
  310.             Curr = 0;
  311.     }
  312. #endif
  313.  
  314.     fputs("----- Storage -----\n", TraceFile);
  315.     MemBlock = MemAnchor;
  316.     if (MemAnchor == NULL)
  317.         fputs("  No Storage On Chain\n", TraceFile);
  318.     else
  319.     {
  320.         for(;;)
  321.         {
  322.             fprintf(TraceFile,
  323.                 "M---%p---%d---%s---%d---%c---%c---%d---%p---%p---%p\n",
  324.                     MemBlock,
  325.                     MemBlock->MemOK,
  326.                     MemBlock->MemMod,
  327.                     MemBlock->MemLine,
  328.                     MemBlock->MemFun,
  329.                     MemBlock->MemUse,
  330.                     MemBlock->MemLen,
  331.                     MemBlock->MemAddr,
  332.                     MemBlock->MemPrev,
  333.                     MemBlock->MemNext);
  334.             MemWork = MemBlock->MemNext;
  335.             if (MemWork == NULL)
  336.                 break;
  337.             MemBlock = MemWork;
  338.         }
  339.     }
  340.  
  341.     fclose(TraceFile);
  342.     exit(ExitCode);
  343. }
  344.